/*
 * TcpClient.cpp
 *
 *   Created on: 2010-1-29     
 *  Description: 
 *    Copyright: 2010 @ ICT Li Heyuan
 */

#include "../../include/client/TcpClient.h"
#include "../../include/json_cpp/json.h"
#include "../../include/util/JsonRpcException.h"
using Json::Reader;
using Json::FastWriter;

#include <string>
#include <iostream>
using std::string;
using std::cout;
using std::endl;

bool TcpClient::_notification(const string &sendBuf, unsigned int timeout /*=
 3*/)
{

	int sock = -1;
	try
	{
		sock = Network::socket();

		//创建sock，设置超时，非阻塞
		//Network::setNonBlocking(sock);
		Network::setTimeOut(sock, timeout);

		//连接
		if (!Network::connect(sock, _serverAddr))
		{
			//连接失败
			throw "send() on sock fail.";
		}
		else
		{
			unsigned long nLeft; //是否eof,发送剩下多少字节

			nLeft = sendBuf.size();
			while (nLeft)
			{
				if (!Network::sendBytes(sock, sendBuf, nLeft))
				{
					//发送出错
					Network::close(sock);
					return false;
				}
			}

			//接收，等待Server关闭
			string recvBuf;//接受数据的缓冲区
			bool eof = false;
			while (!eof)
			{
				if (!Network::recvBytes(sock, recvBuf, eof))
				{
					throw "recv() on sock fail.";
				}
			}
			//Client关闭
			Network::close(sock);
			return true;
		}//end connect success
	} catch (...)
	{
		//出错
		Network::close(sock);
		return false;
	}

}

bool TcpClient::_call(const string &sendBuf, Json::Value &result,
		unsigned int timeout /*=
 3*/)
{

	int sock = -1;
	try
	{
		sock = Network::socket();

		//创建sock，设置超时，非阻塞
		//Network::setNonBlocking(sock);
		Network::setTimeOut(sock, timeout);

		//连接
		if (!Network::connect(sock, _serverAddr))
		{
			//连接失败
			throw JsonRpcException("connect fail.");
		}
		else
		{
			//发送数据
			unsigned long nLeft; //是否eof,发送剩下多少字节
			nLeft = sendBuf.size();
			while (nLeft)
			{
				if (!Network::sendBytes(sock, sendBuf, nLeft))
				{
					//发送出错
					throw JsonRpcException("send() on sock fail.");
				}
			}

			//接收string recvBuf;//发送、接受数据的缓冲区
			bool eof = false;
			string recvBuf;
			Json::Reader reader;
			Json::Value tmp;
			while (!eof)//当server先关闭，退出recv()
			{
				if (!Network::recvBytes(sock, recvBuf, eof))
				{
					throw JsonRpcException("recv() on sock fail.");
				}

				//如果需要client先关闭
				if (eof || _closeFirst)
				{
					//尝试是否得到了response
					try
					{
						bool parseRet = reader.parse(recvBuf, tmp);
						if (parseRet && !tmp.isNull() && tmp.isObject())
						{
							//是完整的response，关闭sock
							Network::close(sock);
							break;
						}
					} catch (...)
					{
						if (eof)
						{
							break;
						}
					}
				}//end if _closeFirst
			}

			//检查结果
			if (tmp["error"] == Json::nullValue)
			{
				result = tmp["result"];
				return true;
			}
			else
			{
				result = tmp["error"];
				return false;
			}
		}//end connect success
	} catch (JsonRpcException &exception)
	{
		Network::close(sock);
		result = exception.what();
		return false;
	} catch (...)
	{
		//出错
		Network::close(sock);
		result = "unknown error.";
		return false;
	}

}
